//
//  ViewController.swift
//  myhub
//
//  Created by x on 2024/3/6.
//

import UIKit
//import EmptyDataSet_Swift
import Hero
import Localize_Swift
import SVProgressHUD
import RxCocoa
import RxSwift
import XResources
import XLog
import XDesignKit

open class ViewController: UIViewController {
    open var viewModel: ViewModel?

    public init(viewModel: ViewModel?) {
        self.viewModel = viewModel
        super.init(nibName: nil, bundle: nil)
    }

    public required init?(coder: NSCoder) {
//        super.init(coder: coder)
        super.init(nibName: nil, bundle: nil)
    }

    public let isLoading = BehaviorRelay(value: false)
    public let error = PublishSubject<ApiError>()

    open var automaticallyAdjustsLeftBarButtonItem = true
    open var canOpenFlex = true

    open var navigationTitle = "" {
        didSet {
            navigationItem.title = navigationTitle
        }
    }

    public let spaceBarButton = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)

    public let emptyDataSetButtonTap = PublishSubject<Void>()
    open var emptyDataSetTitle = R.string.localizable.commonNoResults.key.localized()
    open var emptyDataSetDescription = ""
    open var emptyDataSetImage = R.image.circleHelp()
    open var emptyDataSetImageTintColor = BehaviorRelay<UIColor?>(value: nil)

    public let languageChanged = BehaviorRelay<Void>(value: ())

    public let orientationEvent = PublishSubject<Void>()
    public let motionShakeEvent = PublishSubject<Void>()

    open lazy var searchBar: SearchBar = {
        let view = SearchBar()
        return view
    }()

    open lazy var backBarButton: BarButtonItem = {
        let btn = BarButtonItem()
        btn.title = ""
        return btn
    }()

    open lazy var closeBarButton: BarButtonItem = {
        let btn = BarButtonItem(image: R.image.closeOutline(), style: .plain, target: self, action: nil)
        return btn
    }()

//    lazy var bannerView: GADBannerView = {
//        
//    }()
    open lazy var contentView: View = {
        let view = View()
        self.view.addSubview(view)
        view.snp.makeConstraints { make in
            make.edges.equalTo(self.view.safeAreaLayoutGuide)
        }
        return view
    }()

    open lazy var stackView: StackView = {
        let subviews: [UIView] = []
        let view = StackView(arrangedSubviews: subviews)
        view.spacing = 0
        self.contentView.addSubview(view)
        view.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        return view
    }()

    open override func viewDidLoad() {
        super.viewDidLoad()
        makeUI()
        bindViewModel()

        closeBarButton.rx.tap.asObservable().subscribe(onNext: { [weak self] () in
            self?.dismiss(animated: true, completion: nil)
        }).disposed(by: rx.disposeBag)

        // Observe device orientation change
        NotificationCenter.default.rx.notification(UIDevice.orientationDidChangeNotification).mapToVoid().bind(to: orientationEvent).disposed(by: rx.disposeBag)

        orientationEvent.subscribe {
            [weak self] (event) in
            self?.orientationChanged()
        }.disposed(by: rx.disposeBag)

        NotificationCenter.default.rx.notification(UIApplication.didBecomeActiveNotification).subscribe {
            [weak self] (event) in
            self?.didBecomeActive()
        }.disposed(by: rx.disposeBag)

        NotificationCenter.default.rx.notification(UIAccessibility.reduceMotionStatusDidChangeNotification).subscribe {
            (event) in
            logDebug("Motion Status changed")
        }.disposed(by: rx.disposeBag)

        // 监听语言改变通知
        NotificationCenter.default.rx.notification(NSNotification.Name(LCLLanguageChangeNotification)).subscribe {
            [weak self] (event) in
            self?.languageChanged.accept(())
        }.disposed(by: rx.disposeBag)

        // 一个手指滑动打开FLEX
        let swipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleOneFingerSwipe(swipeRecognizer:)))
        swipeGesture.numberOfTouchesRequired = 1
        self.view.addGestureRecognizer(swipeGesture)

        let twoSwipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleTwoFingerSwipe(swipeRecognizer:)))
        swipeGesture.numberOfTouchesRequired = 2
        self.view.addGestureRecognizer(twoSwipeGesture)
    }
    public override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        if automaticallyAdjustsLeftBarButtonItem {
            adjustLeftBarButtonItem()
        }
        updateUI()
    }
    public override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        updateUI()
        logResourcesCount()
    }

    deinit {
        logDebug("\(type(of: self)): Deinited")

        logResourcesCount()
    }

    public override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
        logDebug("\(type(of: self)): Received Memory Warning")
    }
    open func bindViewModel() {
        viewModel?.loading.asObservable().bind(to: isLoading).disposed(by: rx.disposeBag)
        viewModel?.parsedError.asObservable().bind(to: error).disposed(by: rx.disposeBag)

        languageChanged.subscribe(onNext: { [weak self] () in
            self?.emptyDataSetTitle = R.string.localizable.commonNoResults.key.localized()
        }).disposed(by: rx.disposeBag)

        isLoading.subscribe(onNext: { isLoading in
//            if #available(iOS 13, *) {
//                
//            } else {
//                UIApplication.shared.isNetworkActivityIndicatorVisible = isLoading
//            }
            UIApplication.shared.isNetworkActivityIndicatorVisible = isLoading
        }).disposed(by: rx.disposeBag)
    }

    open func makeUI() {
        hero.isEnabled = true
        navigationItem.backBarButtonItem = backBarButton

        motionShakeEvent.subscribe(onNext: { () in
            let theme = themeService.type.toggled()
            themeService.switch(theme)
        }).disposed(by: rx.disposeBag)

        view.theme.backgroundColor = themeService.attribute { $0.primaryDark }
        backBarButton.theme.tintColor = themeService.attribute { $0.secondary }
        closeBarButton.theme.tintColor = themeService.attribute { $0.secondary }
        theme.emptyDataSetImageTintColorBinder = themeService.attribute { $0.text }

        updateUI()
    }

    open func updateUI() {

    }

    open func startAnimating() {
        SVProgressHUD.show()
    }

    open func stopAnimating() {
        SVProgressHUD.dismiss()
    }
    open override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
        if motion == .motionShake {
            motionShakeEvent.onNext(())
        }
    }

    open func orientationChanged() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
            self.updateUI()
        }
    }
    open func didBecomeActive() {
        self.updateUI()
    }
    // MARK: Adjusting Navigation Item
    open func adjustLeftBarButtonItem() {
        if self.navigationController?.viewControllers.count ?? 0 > 1 { // Pushed
            self.navigationItem.leftBarButtonItem = nil
        } else if self.presentationController != nil { // presented
            self.navigationItem.leftBarButtonItem = closeBarButton
        }
    }

    @objc open func closeAction(sender: AnyObject) {
        self.dismiss(animated: true, completion: nil)
    }
}

public extension ViewController {

    var inset: CGFloat {
        return Dimensions.inset
    }

    func emptyView(withHeight height: CGFloat) -> View {
        let view = View()
        view.snp.makeConstraints { (make) in
            make.height.equalTo(height)
        }
        return view
    }
    @objc func handleOneFingerSwipe(swipeRecognizer: UISwipeGestureRecognizer) {
//        if swipeRecognizer.state == .recognized, canOpenFlex {
//            LibsManager.shared.showFlex()
//        }
    }

    @objc func handleTwoFingerSwipe(swipeRecognizer: UISwipeGestureRecognizer) {
        if swipeRecognizer.state == .recognized {
//            LibsManager.shared.showFlex()
            HeroDebugPlugin.isEnabled = !HeroDebugPlugin.isEnabled
        }
    }
}

extension ViewController: EmptyDataSetSource {

    public func title(forEmptyDataSet scrollView: UIScrollView!) -> NSAttributedString! {
        return NSAttributedString(string: emptyDataSetTitle)
    }

    public func description(forEmptyDataSet scrollView: UIScrollView!) -> NSAttributedString! {
        return NSAttributedString(string: emptyDataSetDescription)
    }

    public func image(forEmptyDataSet scrollView: UIScrollView!) -> UIImage! {
        return emptyDataSetImage
    }

    public func imageTintColor(forEmptyDataSet scrollView: UIScrollView!) -> UIColor! {
        return emptyDataSetImageTintColor.value
    }

    public func backgroundColor(forEmptyDataSet scrollView: UIScrollView!) -> UIColor! {
        return .clear
    }

    public func verticalOffset(forEmptyDataSet scrollView: UIScrollView!) -> CGFloat {
        return -60
    }
}

extension ViewController: EmptyDataSetDelegate {

    public func emptyDataSetShouldDisplay(_ scrollView: UIScrollView!) -> Bool {
        return !isLoading.value
    }

    public func emptyDataSetShouldAllowScroll(_ scrollView: UIScrollView!) -> Bool {
        return true
    }

    public func emptyDataSet(_ scrollView: UIScrollView!, didTap button: UIButton!) {
        emptyDataSetButtonTap.onNext(())
    }
}
